const replaceTokens = 'ymdhMs'.split('');
// 一天的秒数
const S_A_DAY = 24 * 3600;
// 一天的毫秒数
const MS_A_DAY = 1000 * S_A_DAY;

/**
 * 格式化字符串输出
 * @param {string} str 格式化字符串
 * @param {number|string} ts 时间戳（秒）
 */
function format(str, ts) {
    if (!str || !ts) return '';
    const d = parseDate(ts);

    let result = str;
    replaceTokens.forEach((t) => {
        result = result.replace(`%${t}`, p2(d[t]));
    });

    return result;
}

function parseDate(ts) {
    const d = new Date(ts * 1000);
    return {
        y: d.getFullYear() /* 年 */,
        m: d.getMonth() + 1 /* 月 */,
        d: d.getDate() /* 日 */,
        h: d.getHours() /* 时 */,
        M: d.getMinutes() /* 分 */,
        s: d.getSeconds() /* 秒 */,
    };
}

function p2(n) {
    if (n < 10) return '0' + n;
    return '' + n;
}

/**
 * 判断是否同一天
 * @param {number|string} t0 时间戳（秒）
 * @param {number|string} t1 时间戳（秒）
 */
function isSameDay(t0, t1) {
    if (isNaN(t0) || isNaN(t1)) return false;

    if (t0 == t1) return true;

    const d0 = parseDate(t0);
    const d1 = parseDate(t1);

    return d0.y === d1.y && d0.m === d1.m && d0.d === d1.d;
}

/**
 * Check if year is leap
 * @param {number} year
 * @returns {boolean}
 */
function isLeap(year) {
    return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}

/**
 * 计算N天前后的时间戳，返回的时间戳以秒为单位
 * @param {number} startTime 起始时间戳，以秒为单位
 * @param {number} delta 天数差异
 */
export function diffDays(startTime = 0, delta = 0) {
    return startTime + delta * S_A_DAY;
}

/**
 * 计算起止时刻之间包含的天数
 * @param {number} startTime 开始时刻，以秒为单位
 * @param {number} endTime 结束时刻，以秒为单位
 */
export function calculateDaysBetween(startTime = 0, endTime = 0) {
    return (endTime - startTime) / S_A_DAY;
}

/**
 * 计算某天的开始时刻
 * @param {number} dayTime 时间戳，以秒为单位
 */
export function startOfDay(dayTime) {
    if (!dayTime) return 0;

    const date = new Date(dayTime * 1000);
    const startOfDate = new Date(
        date.getFullYear(),
        date.getMonth(),
        date.getDate()
    );
    return startOfDate.getTime() / 1000;
}

/**
 * 获取日期是当年的第几天
 * @param {Date} date
 * @returns {number} 这是当年第几天
 */
export function getDayOfYear(date) {
    const daysInMonth = getDaysInMonth(date.getFullYear());
    const months = daysInMonth.slice(0, date.getMonth());

    return months.reduce((a, b) => a + b, 0) + date.getDate();
}

/**
 * get days of each month
 * @param {number} year
 * @returns {number[]}
 */
function getDaysInMonth(year) {
    const leap = isLeap(year);
    const JAN = 31;
    const FEB = leap ? 29 : 28;
    const MAR = 31;
    const APR = 30;
    const MAY = 31;
    const JUN = 30;
    const JUL = 31;
    const AUG = 31;
    const SEP = 30;
    const OCT = 31;
    const NOV = 30;
    const DEC = 31;
    return [JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC];
}

export default {
    format,
    isSameDay,
    isLeap,
};
